﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.MinPack
{
    /// <summary>
    /// For further information view the MinPack documentation.
    /// </summary>
    [Serializable]
    public static class Lmdif0Class
    {
        /// <summary>
        /// For further information view the MinPack documentation.
        /// </summary>
        /// <param name="fcn">The fcn parameter.</param>
        /// <param name="m">The m parameter.</param>
        /// <param name="n">The n parameter.</param>
        /// <param name="x">The x parameter.</param>
        /// <param name="msk">The MSK parameter.</param>
        /// <param name="fvec">The fvec parameter.</param>
        /// <param name="tol">The tol parameter.</param>
        /// <param name="info">The info parameter.</param>
        /// <param name="nfev">The nfev parameter.</param>
        /// <returns>For further information view the MinPack documentation.</returns>
        public static int Lmdif0(MinPackFunction fcn, int m, int n, double[] x, int[] msk,
                                 double[] fvec, double tol, ref int info, ref int nfev)
        {
            int[] ipvt = new int[n];
            double[] diag = new double[n];
            double[] qtf = new double[n];
            double[] wa1 = new double[n];
            double[] wa2 = new double[n];
            double[] wa3 = new double[n];
            double[] wa4 = new double[m];
            double[,] fjac = new double[n,m];

            //Check input parameters
            if (n <= 0 || m < n || tol < 0.0)
            {
                info = 0;
                return 1;
            }

            //Set convergence tolerances
            double ftol = tol;
            double xtol = tol;
            const double gtol = 0.0;

            const int maxfev = 800;
            const double epsfcn = 0.0;
            const int mode = 1;
            const double factor = 10;

            nfev = 0;

            LmdifClass.Lmdif(fcn, m, n, x, msk, fvec, ftol, xtol, gtol, maxfev, epsfcn, diag, mode,
                             factor, ref info, ref nfev, fjac, ipvt, qtf, wa1, wa2, wa3, wa4);

            if (info == 8)
            {
                info = 4;
            }

            return 0;
        }
    }
}